#include "ipacket.h"

#include "reader.h"
#include "writer.h"
#include "request.h"

namespace pack {

Request::Request(net::IBuffer* buffer) {
	buf = NULL;
	buf_size = 0;

	uri = 0;
	size = 0;

	external_buffer = buffer;
	internal_buffer = net::GetBuffer();	
}

Request::~Request() {
	DestroyBuf();

	if(internal_buffer != NULL) {
		delete internal_buffer;
		internal_buffer = NULL;
	}
}

uint32_t Request::GetUri() {
	return uri;
}

bool Request::Pack(IPacket* packet) {
	net::IBuffer* temp_buffer = net::GetBuffer();
	Writer writer(external_buffer);
	Writer temp_writer(temp_buffer);

	//1.先打包到temp中去，以便获取packet的大小
	packet->Pack(temp_writer);

	//2.获取packet的uri和size
	uri = packet->GetUri();
	size = temp_buffer->GetSize() + 4; //4 = (uri的大小)

	//3.真正打包packet
	writer<<size<<uri;
	packet->Pack(writer);

    delete temp_buffer;
	return true;
}

void Request::DestroyBuf() {
	if(buf != NULL) {
		delete[] buf;
		buf = NULL;
	}
}

void Request::ReallocBuf(uint32_t size) {
	DestroyBuf();

	buf_size = size;
	buf = new char[buf_size];
}

bool Request::GetPack() {
	bool is_unpack = false;
	Reader reader(external_buffer);

	if(external_buffer->GetSize() < 8) { //8 = (size + uri的大小)
		return false;
	}

	//1.锁住缓存的位置
	external_buffer->Hold();

	//2.读取size, 并判断是否是一个完整的包
	reader>>size;
	if(external_buffer->GetSize() < size) {
		external_buffer->Revert(); //不是一个完整的包,Revert掉
		return false;
	}

	//3.先读取uri，再Unpack整个包
	reader>>uri;

	//把Packet里面的数据读出来
	if(buf_size < size) {
		ReallocBuf(size);
	}
	external_buffer->Read(buf, size - 4);

	external_buffer->Commit(0); //成功解包，Commit缓存

	//从外部的buffer读取到内部
	internal_buffer->Clean();
	internal_buffer->Write(buf, size);
	return true;
}

bool Request::UnPack(IPacket* packet) {
	bool is_unpack = false;
	Reader reader(internal_buffer);

	//1.锁住缓存的位置
	internal_buffer->Hold();

	is_unpack = packet->UnPack(reader); //注：操作的buffer是内部的

	//2.还原内部的buffer
	internal_buffer->Revert();
	return is_unpack;
}

}
